package com.xcity.robot.net.pomelo;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.xcity.robot.net.packet.BinaryPacket;
import com.xcity.robot.net.pomelo.Message.Type;
import com.xcity.robot.net.util.SessionUtils;

import naga.x.App;
import naga.x.net.impl.pomelo.PomeloMessage;
import naga.x.net.impl.pomelo.PomeloPacket;
import naga.x.net.impl.pomelo.protocol.Package;

public class PomeloEncoder extends ProtocolEncoderAdapter {

	@Override
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
		if (!(message instanceof PomeloPacket)) {
			throw new IllegalArgumentException("Can't encode the message: " + (message != null ? message.getClass() : null) + " -> " + message);
		}
		PomeloPacket packet = (PomeloPacket) message;
		byte[] buf;
		if (packet.getPackageType() != Package.TYPE_DATA) {
			buf = Package.encode(packet.getPackageType(), ((BinaryPacket) packet).toBinary());
		} else {
			PomeloMessage pm = packet.getClass().getDeclaredAnnotation(PomeloMessage.class);
			String route = pm.type().msgHasRoute() ? pm.route() : "";
			boolean compressRoute = pm.type().msgHasRoute()
					&& App.getApp().getConfig().getDictionary().getRouteCode(route.toString()) != -1;
			Message msg = new Message(packet.getSerial(), Type.codeOf(pm.type().ordinal()), compressRoute, route, packet, false);
			buf = Package.encode(packet.getPackageType(), Message.encode(msg));
			// record request
			Map<Integer, String> requestMap = (Map<Integer, String>) session.getAttribute(SessionUtils.REQUEST_MAP);
			if (requestMap == null) {
				requestMap = new LinkedHashMap<Integer, String>();
				session.setAttribute(SessionUtils.REQUEST_MAP, requestMap);
			}
			requestMap.put(packet.getSerial(), route);
		}
		out.write(buf);
	}
	
}
